
#include "clib_hash_fnv64.h"


#define CLIB_FNV64_PRIME          (1099511628211ULL)
#define CLIB_FNV64_OFFSET_BASIS   (14695981039346656037ULL)

clib_uint64_t clib_hash_fnv64_1(clib_uint8_t const *data, size_t size, clib_uint64_t seed) {
    clib_check_if_true_return_value(data == NULL, 0);
    clib_check_if_true_return_value(size == 0, 0);
    clib_uint64_t value = CLIB_FNV64_OFFSET_BASIS;
    if (seed) {
        value = (value * CLIB_FNV64_PRIME) ^ seed;
    }
    while (size) {
        value *= CLIB_FNV64_PRIME;
        value ^= (clib_uint64_t) *data++;
        size--;
    }
    return value;
}

clib_uint64_t clib_hash_fnv64_1_from_string(char const *string, clib_uint64_t seed) {
    clib_check_if_true_return_value(string == NULL, 0);
    return clib_hash_fnv64_1((clib_uint8_t const *) string, strlen(string) + 1, seed);
}


clib_uint64_t clib_hash_fnv64_1a(clib_uint8_t const *data, size_t size, clib_uint64_t seed) {
    clib_check_if_true_return_value(data == NULL, 0);
    clib_check_if_true_return_value(size == 0, 0);
    clib_uint64_t value = CLIB_FNV64_OFFSET_BASIS;
    if (seed) {
        value = (value * CLIB_FNV64_PRIME) ^ seed;
    }
    while (size) {
        value ^= (clib_uint64_t) *data++;
        value *= CLIB_FNV64_PRIME;
        size--;
    }
    return value;
}


clib_uint64_t clib_hash_fnv64_1a_from_string(char const *string, clib_uint64_t seed) {
    clib_check_if_true_return_value(string == NULL, 0);
    return clib_hash_fnv64_1a((clib_uint8_t const *) string, strlen(string) + 1, seed);
}
